#include "register.h"

char loginUserName[128] = {0}; // 登入用户的名字
sem_t sem1;                    // 一组信号量用来控制主线程和子线程的输入输出
sem_t sem2;
sem_t sem3;
sem_t sem4;
sem_t sem5;
sem_t sem6;
ltjr temp = {0};    // 用来保存上一条聊天记录，如果和下一条聊天记录时间一致就合并输出
int tty_size = 0;   // 终端行长度
void *work(void *p) // 用户主动退出，线程才能关闭
{
    workAddr waddr = *(workAddr *)p;
    package pack;
    while (1)
    {
        recvfrom(waddr.fd, &pack, sizeof(pack), 0, NULL, NULL); // 接收服务器转发的消息包
        if (pack.msgType == QUNLIAO)                            // 群聊
        {
            mtalk mta = *(mtalk *)pack.msgBlock; // 拆包
            printf("\e[34m%s(群发):%s\n\e[0m", mta.name, mta.text);
        }
        else if (pack.msgType == DANLIAO) // 私聊
        {
            ptalk pta = *(ptalk *)pack.msgBlock;
            if (pta.flag == 1)
            {
                printf("\e[31m服务器提示消息:%s\e[0m\n", pta.text);
                printf("\e[33m请输入quit退出私聊界面\e[0m\n");
            }
            else if (pta.flag == 0)
            {
                if (!strcmp(pta.text, "quit"))
                {
                    printf("\e[33m好友%s退出聊天了\e[0m\n", pta.srcname);
                }
                else
                {
                    printf("\e[34m好友%s(私发):%s\e[0m\n", pta.srcname, pta.text);
                }
            }
        }
        else if (pack.msgType == APPLY)
        {
            friendApr fri = *(friendApr *)pack.msgBlock;
            // 只有接收方才能收到
            if (fri.type == REQUEST) // 请求添加好友
            {
                printf("\e[31m%s申请添加你为好友\e[0m\n", fri.myname);
                sem_wait(&sem2);
                printf("\e[31m%s申请添加你为好友\e[0m\n", fri.myname);
                printf("\e[33m请输入你的选择(同意或者拒绝):\e[0m");
                char sel[20];
                scanf("%s", sel);
                if (!strcmp(sel, "同意")) // 同意好友申请
                {
                    fri.type = AGREE; // 修改状态，同意好友申请
                    memcpy(pack.msgBlock, &fri, sizeof(fri));
                    sendto(waddr.fd, &pack, sizeof(pack), 0, (struct sockaddr *)&waddr.addr, sizeof(struct sockaddr_in));
                }
                else // 拒绝
                {
                    fri.type = REFUSE; // 修改为拒绝
                    memcpy(pack.msgBlock, &fri, sizeof(fri));
                    sendto(waddr.fd, &pack, sizeof(pack), 0, (struct sockaddr *)&waddr.addr, sizeof(struct sockaddr_in));
                }
                sem_post(&sem1);
            }
            // 只有发送好友申请的才能收到
            else if (fri.type == AGREE)
            {
                printf("\e[31m%s同意了你的好友申请,你们已经是好友了\e[0m\n", fri.hisname);
            }
            //
            else if (fri.type == REFUSE)
            {
                printf("\e[31m%s拒绝了你的好友申请\e[0m\n", fri.hisname);
            }
            else if (fri.type == NOBODY)
            {
                printf("%s\n", fri.myname);
            }
        }
        else if (pack.msgType == HAOYOU)
        {
            sem_wait(&sem3);
            friendList fli = *(friendList *)pack.msgBlock;
            printf("----\e[36m%s的好友列表\e[0m----\n", fli.name);
            if (fli.num == 0)
            {
                printf("\n[1;31m你还没有好友!\e[0m\n");
            }
            else
            {
                printf("\e[33m共有%d位好友\e[0m\n", fli.num);
                printf("\e[32m好友\t状态\e[0m\n");
                for (int i = 0; i < fli.num; i++)
                {
                    if (!strcmp(fli.flist[i].isLine, "在线"))
                    {
                        printf("\e[34m%s\t%s\e[0m\n", fli.flist[i].name, fli.flist[i].isLine);
                    }
                    else
                    {
                        printf("%s\t%s\n", fli.flist[i].name, fli.flist[i].isLine);
                    }
                }
            }
            sem_post(&sem1);
        }
        else if (pack.msgType == DONGTAI)
        {
            sem_wait(&sem5);
            pyq tiez = *(pyq *)pack.msgBlock;
            if (tiez.flag == 0)
            {
                printf("\e[31m发表成功,等待好友评论和点赞\e[0m\n");
                sem_post(&sem1);
            }
            else if (tiez.flag == 1) // 至少有一条朋友圈
            {
                while (1)
                {
                    printf("\e[36m%s\t%s\e[0m\n", tiez.time, tiez.name);
                    printf("  \e[34m%s\n\n\e[0m", tiez.text);
                    recvfrom(waddr.fd, &pack, sizeof(pack), 0, NULL, NULL);
                    tiez = *(pyq *)pack.msgBlock;
                    if (tiez.flag == 2)
                    {
                        break;
                    }
                }
                sem_post(&sem1);
            }
            else if (tiez.flag == 3) // 先打印再退出
            {
                printf("\e[31m%s\t%s\e[0m\n", tiez.time, tiez.name);
                printf("  \e[31m%s\n\n\e[0m", tiez.text);
                sem_post(&sem1);
            }
        }
        else if (pack.msgType == JIRU)
        {
            sem_wait(&sem4);
            opjr op1 = *(opjr *)pack.msgBlock;
            if (op1.flag == 0) // 清空完成
            {
                printf("\e[31m清空聊天记录成功\n\e[0m");
                sem_post(&sem1); // 回到菜单栏
            }
            else // 查看聊天记录
            {
                // 想查看那一天的聊天记录也可以，只需要对时间进行分类查看输出就行
                if (op1.isOK == 0) // 还没传完
                {
                    if (strcmp(op1.lt.time, temp.time)) // 时间不相同
                    {
                        // 时间居中对齐输出
                        for (int i = 0; i < (tty_size - strlen(op1.lt.time) + 4) / 2; i++)
                            printf(" ");
                        printf("%s\n", op1.lt.time);
                    }
                    if (strcmp(loginUserName, op1.lt.name)) // 不是自己发的
                    {
                        if (strcmp(op1.lt.text, "quit"))
                        {
                            printf("\e[34m%s:%s\e[0m\n", op1.lt.name, op1.lt.text); // 蓝色对方用，自古红蓝出CP
                        }
                    }
                    else
                    {
                        /*因为在UTF-8编码中汉字占3个字节，但在终端输出是占2个空格
                          因此汉字字符串要乘以2/3，但因为字符串中不全是汉字，因此算出来的
                          结果会偏小，输出的空格过多，以至于想要字符串输出紧靠终端行末而溢出
                          到下一行，在这里没有实现汉字和普通字符的区分，有待下一步提高
                        */
                        if (strcmp(op1.lt.text, "quit")) // 不打印quit
                        {
                            char buf[256];
                            sprintf(buf, "%s:%s", op1.lt.text, op1.lt.name);
                            for (int i = 0; i < tty_size - strlen(buf) * 2 / 3 - 2; i++)
                                printf(" ");
                            printf("\e[31m%s\n\e[0m", buf);
                        }
                    }
                    temp = op1.lt;   // temp是上一条聊天记录
                    sem_post(&sem4); // 让线程继续接收消息
                }
                else // 传输完成
                {
                    sem_post(&sem1);
                }
            }
        }
        else if (pack.msgType == CSFILE)
        {
            chuanShou chs = *(chuanShou *)pack.msgBlock;
            if (chs.type == CHUAN)
            {
                printf("\e[33m你的好友%s给你发送了一个文件:%s\e[0m\n", chs.srcname, chs.filename);
                continue;
            }
            else if (chs.type == SHOU)
            {
                // 发送方
                if (chs.data.isOK == 2)
                {
                    printf("\e[33m你的好友%s接收了你的文件:%s\e[0m\n", chs.desname, chs.filename);
                    continue;
                }
                else
                {
                    // 接收方
                    sem_wait(&sem6);
                    int dir_mode = 0755; // 目录权限
                    char dirname[128];
                    sprintf(dirname, "./customer_file/%s", loginUserName);
                    if (mkdir(dirname, dir_mode) == -1)
                    {
                        if (errno != EEXIST) // 如果创建失败
                        {
                            perror("Failed to create directory A");
                            continue;
                        }
                    }
                    char clientfile[128];
                    sprintf(clientfile, "./customer_file/%s/%s_%s", loginUserName, chs.srcname, chs.filename); // 指定下载目录，这里我直接指定了一个目录
                    int fd = open(clientfile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
                    int rcvsize = 0;
                    while (1)
                    {
                        if (write(fd, chs.data.text, chs.data.bytes) != chs.data.bytes)
                        {
                            perror("write wrong");
                            close(fd);
                            break;
                        }
                        rcvsize += chs.data.bytes;
                        printf("已下载%d个字节\n", rcvsize);
                        if (chs.data.isOK == 1)
                        {
                            printf("下载完毕\n");
                            close(fd);
                            break;
                        }
                        recvfrom(waddr.fd, &pack, sizeof(pack), 0, NULL, NULL);
                        chs = *(chuanShou *)pack.msgBlock;
                    }
                    sem_post(&sem1);
                }
            }
        }
    }
}

void dongHua()
{
    struct winsize w;
    ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
    int rows = w.ws_row; // 终端多宽
    int cols = w.ws_col; // 终端多长
    tty_size = cols;
    for (int i = 0; i < cols - 10; i++)
    {
        for (int j = 0; j < 6 + i; j++)
            printf(" ");
        printf("\e[32m|\\\n\e[0m");

        for (int j = 0; j < 6 + i; j++)
            printf(" ");
        printf("\e[32m| \\\n\e[0m");

        for (int j = 0; j < i; j++)
            printf(" ");
        printf("\e[32m______|  \\\e[0m\n");

        for (int j = 0; j < i; j++)
            printf(" ");
        printf("\e[32m|         \\\e[0m\n");

        for (int j = 0; j < i; j++)
            printf(" ");
        printf("\e[32m|         /\e[0m\n");

        for (int j = 0; j < i; j++)
            printf(" ");
        printf("\e[32m|_____   /\e[0m\n");

        for (int j = 0; j < 6 + i; j++)
            printf(" ");
        printf("\e[32m| /\n\e[0m");

        for (int j = 0; j < 6 + i; j++)
            printf(" ");
        printf("\e[32m|/\n\e[0m");

        usleep(30000);
        printf("\e[H\e[J");
    }
    printf("\e[H\e[J");
    printf("\e[1;32m登录成功\e[0m\n");
    printf("\t\t\e[1;31mW  2  X\e[0m\n");
}

void registerUser(int sd, struct sockaddr_in *addr)
{
    zhuce info; // 注册信息结构体
    printf("\e[33m请依次输入你要注册的账号、电话号码、密码:\e[0m\n");
    scanf("%s %s %s", info.name, info.tel, info.pwd);
    package pack;                               // 用来封装信息结构体
    memcpy(pack.msgBlock, &info, sizeof(info)); // 封装成统一的包
    pack.msgType = REGISTER;                    // 贴上消息类型标签
    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
    recvfrom(sd, &pack, sizeof(pack), 0, NULL, NULL);
    printf("%s\n", pack.msgBlock);
}

void seekPwd(int sd, struct sockaddr_in *addr)
{
    mima mm;
    puts("\e[33m请输入你要找回的账号:\e[0m");
    scanf("%s", mm.name);
    puts("\e[33m请输入你绑定的电话号码来找回密码:\e[0m");
    scanf("%s", mm.tel);
    package pack;
    memcpy(pack.msgBlock, &mm, sizeof(mm));
    pack.msgType = SEEKPWD;
    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
    recvfrom(sd, &pack, sizeof(pack), 0, NULL, NULL);
    printf("%s\n", pack.msgBlock);
}

void deletePwd(int sd, struct sockaddr_in *addr)
{
    zhuce zh;
    printf("\e[33m请输入你要注销的账号:\e[0m");
    scanf("%s", zh.name);
    printf("\e[33m请输入你绑定的电话号码:\e[0m");
    scanf("%s", zh.tel);
    printf("\e[33m请输入你的密码:\e[0m");
    scanf("%s", zh.pwd);
    package pack;
    pack.msgType = ZHUXIAO;
    memcpy(pack.msgBlock, &zh, sizeof(zh));
    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
    recvfrom(sd, &pack, sizeof(pack), 0, NULL, NULL);
    printf("%s\n", pack.msgBlock);
}
void changePwd(int sd, struct sockaddr_in *addr)
{
    newPwd npd;
    printf("\e[33m请输入你要修改的账号:\e[0m");
    scanf("%s", npd.name);
    printf("\e[33m请输入账号原密码:\e[0m");
    scanf("%s", npd.opwd);
    printf("\e[33m请输入账号新密码:\e[0m");
    scanf("%s", npd.npwd);
    package pack;
    pack.msgType = XIUGAI;
    memcpy(pack.msgBlock, &npd, sizeof(npd));
    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
    recvfrom(sd, &pack, sizeof(pack), 0, NULL, NULL);
    printf("%s\n", pack.msgBlock);
}
void exitSys(int sd, struct sockaddr_in *addr)
{
    package pack;
    char buf[128] = "退出系统";
    memcpy(pack.msgBlock, buf, sizeof(buf));
    pack.msgType = TUICHU;
    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
    recvfrom(sd, &pack, sizeof(pack), 0, NULL, NULL);
    printf("\e[H\e[J"); // 清屏
    printf("%s\n", pack.msgBlock);
    close(sd);
    exit(0);
}

void dengluUser(int sd, struct sockaddr_in *addr)
{
    denglu info;
    puts("\e[33m请输入你要登录的账号和密码:\e[0m");
    scanf("%s %s", info.name, info.pwd);
    package pack;
    memcpy(pack.msgBlock, &info, sizeof(info));
    pack.msgType = DENGLU;
    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
    recvfrom(sd, &pack, sizeof(pack), 0, NULL, NULL);
    if (!strcmp(pack.msgBlock, "登录成功")) // 登入成功继续
    {
        strcpy(loginUserName, info.name); // 拷贝名字用于发送
        next_menu(sd, addr);
    }
    else
    {
        printf("%s\n", pack.msgBlock);
    }
}

void next_menu(int sd, struct sockaddr_in *addr)
{
    dongHua(); // 登录动画
    workAddr p;
    p.fd = sd;
    p.addr = *addr;
    sem_init(&sem1, 0, 1);
    sem_init(&sem2, 0, 0);
    sem_init(&sem3, 0, 0);
    sem_init(&sem4, 0, 0);
    sem_init(&sem5, 0, 0);
    sem_init(&sem6, 0, 0);
    pthread_t pt;
    pthread_create(&pt, NULL, work, &p); // 接收消息只需要一个套接字就行
    while (1)
    {
        sem_wait(&sem1);
        printf("\e[32m1.群聊------2.添加好友------3.好友申请\e[0m\n");
        printf("\e[32m4.好友列表--5.退出登录------6.私聊\n\e[0m");
        printf("\e[32m7.朋友圈----8.聊天记录------9.传输文件\e[0m\n");
        printf("\e[32m10.接收文件\e[0m\n");
        int sel;
        printf("select(1-10):");
        scanf("%d", &sel);
        switch (sel)
        {
        case 1: // 群聊
        {
            // 告诉系统你要加入群聊
            mtalk mta;
            package pack;
            mta.type = JIAQUN;                        // 加群申请，不输出消息内容，只保存地址信息和名字
            strcpy(mta.name, loginUserName);          // 告诉大家是谁群发的消息
            memset(mta.text, 0, sizeof(mta.text));    // 没有内容
            memcpy(pack.msgBlock, &mta, sizeof(mta)); // 数据封装
            pack.msgType = QUNLIAO;
            sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));

            printf("\e[33m\t华清嵌入式2403班级群\e[0m\n"); // 进入群聊
            printf("\e[37msystem:输入quit可退出群聊\e[0m\n");
            while (1)
            {
                scanf("%s", mta.text);
                mta.type = QUNMSG;
                memcpy(pack.msgBlock, &mta, sizeof(mta)); // 数据封装
                sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
                if (!strcmp(mta.text, "quit"))
                {
                    printf("\32m退出群聊成功\e[0m\n");
                    break;
                }
            }
            sem_post(&sem1);
        }
        break;

        case 2: // 只能添加登录用户为好友
        {
            friendApr fri;
            package pack;
            pack.msgType = APPLY;
            strcpy(fri.myname, loginUserName); // 谁申请添加好友
            printf("\e[33m请输入你要添加的好友名字:\e[0m");
            scanf("%s", fri.hisname);
            fri.type = REQUEST;
            memcpy(pack.msgBlock, &fri, sizeof(fri));
            sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
            sem_post(&sem1);
        }
        break;

        case 3:
            sem_post(&sem2);
            break;
        case 4:
        {
            friendList fli;
            package pack;
            pack.msgType = HAOYOU;
            // 初始化
            strcpy(fli.name, loginUserName);
            memset(&fli.flist, 0, sizeof(fli.flist));
            fli.num = 0;
            memcpy(pack.msgBlock, &fli, sizeof(fli));
            sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
            sem_post(&sem3);
        }
        break;

        case 5:
        {
            package pack;
            pack.msgType = UEXIT;
            memcpy(pack.msgBlock, loginUserName, sizeof(loginUserName));
            sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
            pthread_cancel(pt); // 取消子线程
            printf("\e[H\e[J");
            return;
        }
        break;
        case 6:
        {
            package pack;
            pack.msgType = DANLIAO;
            ptalk ptk;
            strcpy(ptk.srcname, loginUserName);
            printf("\e[33m请输入你要单聊的好友名字:\e[0m");
            scanf("%s", ptk.desname);
            ptk.flag = 0;
            // 判断是不是好有，好友在不在线
            while (1)
            {
                printf("\e[34m请输入你要发送的消息:\e[0m");
                scanf("%s", ptk.text);
                memcpy(pack.msgBlock, &ptk, sizeof(ptk));
                sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
                if (!strcmp(ptk.text, "quit"))
                {
                    printf("\e[32m退出私聊成功\e[0m\n");
                    break;
                }
            }
            sem_post(&sem1);
        }
        break;

        case 7:
        {
            printf("\e[033m1.发朋友圈------2.看朋友圈\e[0m\n");
            int xz;
            scanf("%d", &xz);
            getchar();
            if (xz == 1)
            {
                package pack;
                pack.msgType = DONGTAI;
                pyq tiez;
                tiez.flag = 0; // 告诉服务器这是发朋友圈
                strcpy(tiez.name, loginUserName);
                time_t t1;
                time(&t1);
                struct tm *now;
                now = localtime(&t1);
                char nowtime[128];
                sprintf(nowtime, "%d年%d月%d日%d时%d分", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min);
                strcpy(tiez.time, nowtime); // 写入时间
                printf("\e[33m请输入你要发表的说说:\e[0m");
                scanf("%[^\n]", tiez.text);
                memcpy(pack.msgBlock, &tiez, sizeof(tiez));
                sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
            }
            else if (xz == 2)
            {
                printf("----------\e[1;32m朋友圈\e[0m----------\n");
                package pack;
                pack.msgType = DONGTAI;
                pyq tiez;
                tiez.flag = 1;
                strcpy(tiez.name, loginUserName);
                memset(tiez.text, 0, sizeof(tiez.text));
                memset(tiez.time, 0, sizeof(tiez.time));
                memcpy(pack.msgBlock, &tiez, sizeof(tiez));
                sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in)); // 告诉服务器你要看朋友圈
            }
            sem_post(&sem5);
        }
        break;
        // 聊天记录需要服务器发送，不能直接从本地文件读取
        case 8:
        {
            printf("\e[35m请输入你要操作的好友名:\e[0m");
            char name[20];
            scanf("%s", name);
            printf("\e[033m1.查看聊天记录------2.清空聊天记录\e[0m\n");
            int xz;
            scanf("%d", &xz);
            opjr op1;
            strcpy(op1.srcname, loginUserName);
            strcpy(op1.desname, name);
            memset(&op1.lt, 0, sizeof(op1.lt));
            op1.isOK = 0;
            if (xz == 1)
            {
                op1.flag = 1;
            }
            else if (xz == 2)
            {
                op1.flag = 0;
            }
            package pack;
            pack.msgType = JIRU;
            memcpy(pack.msgBlock, &op1, sizeof(op1));
            sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
            sem_post(&sem4);
        }
        break;
        case 9:
        {
            package pack;
            pack.msgType = CSFILE;
            printf("\e[33m请输入你要发送的好友名:\e[0m");
            chuanShou chs;
            scanf("%s", chs.desname);
            strcpy(chs.srcname, loginUserName);
            chs.type = CHUAN;
            printf("\e[33m请输入你要发送的文件名:\e[0m");
            scanf("%s", chs.filename);             // 把路径也传过去了,要去掉文件路径
            int fd = open(chs.filename, O_RDONLY); // 打开文件
            char *ch;
            for (int i = 0; i < strlen(chs.filename); i++)
            {
                if (chs.filename[i] == '/')
                {
                    ch = &chs.filename[i];
                }
            }
            ch++; // 去掉文件的路径，只保留文件名
            puts(ch);
            if (fd < 0)
            {
                perror("open fail");
                close(fd);
                continue;
            }
            else
            {
                struct stat info;
                stat(chs.filename, &info);
                int leftSize = info.st_size; // 取出传输文件大小文件
                strcpy(chs.filename, ch);    // 之传输文件名，不包括路径
                printf("%d\n", leftSize);
                int sendSize = 0;
                while (leftSize)
                {
                    if (leftSize > 800)
                    {
                        chs.data.isOK = 0;
                        chs.data.bytes = 800;
                    }
                    else
                    {
                        chs.data.isOK = 1; // 告诉服务器这是最后一个文件块
                        chs.data.bytes = leftSize;
                    }
                    read(fd, chs.data.text, chs.data.bytes);
                    leftSize -= chs.data.bytes;
                    sendSize += chs.data.bytes;
                    memcpy(pack.msgBlock, &chs, sizeof(chs));
                    sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
                    printf("已上传%d字节\n", sendSize);
                    usleep(6);
                }
                close(fd);
                printf("\e[32m文件传输完成\e[0m\n");
            }
            sem_post(&sem1);
        }
        break;
        case 10:
        {
            package pack;
            pack.msgType = CSFILE;
            printf("\e[33m请输入你要下载文件的好友名:\e[0m");
            chuanShou chs;
            scanf("%s", chs.srcname);
            strcpy(chs.desname, loginUserName);
            chs.type = SHOU;
            printf("\e[33m请输入你要接收的文件名:\e[0m");
            scanf("%s", chs.filename); //
            memset(&chs.data, 0, sizeof(chs.data));
            // 告诉服务器你要下载什么文件
            memcpy(pack.msgBlock, &chs, sizeof(chs));
            sendto(sd, &pack, sizeof(pack), 0, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
            // 开始下载文件
            sem_post(&sem6);
        }
        break;
        default:
            sem_post(&sem1);
            break;
        }
    }
}
int main(int argc, char const *argv[])
{
    struct sockaddr_in *addr = getSockAddr("192.168.86.132", 9000);
    int sd = socket(AF_INET, SOCK_DGRAM, 0);
    // 这下面开始写
    // 成功用绿色，出错用红色，黄色提示，蓝色随机应变
    printf("\t\t\e[1;31mW  2  X\e[0m\n");
    while (1)
    {
        printf("\e[33m1.注册------2.登入-------3.找回密码\e[0m\n");
        printf("\e[33m4.修改密码--5.注销账号---6.退出\e[0m\n");
        int sel;
        printf("select(1-6):");
        scanf("%d", &sel);
        if (sel == 1)
        {
            registerUser(sd, addr);
        }
        else if (sel == 2)
        {
            dengluUser(sd, addr);
        }
        else if (sel == 3)
        {
            seekPwd(sd, addr);
        }
        else if (sel == 4)
        {
            changePwd(sd, addr);
        }
        else if (sel == 5)
        {
            deletePwd(sd, addr);
        }
        else
        {
            exitSys(sd, addr);
        }
    }
    return 0;
}
